package pl.edu.agh.winmon;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;

import pl.edu.agh.winmon.dao.SessionDAO;
import pl.edu.agh.winmon.hibernate.Session;
import pl.edu.agh.winmon.util.SessionFactoryBuilder;
import pl.edu.agh.winmon.widget.CPUInfoWidget;
import pl.edu.agh.winmon.widget.MemoryInfoWidget;
import pl.edu.agh.winmon.widget.ProcessInfoWidget;
import pl.edu.agh.winmon.widget.ProgramInfoWidget;
import pl.edu.agh.winmon.widget.SessionUpdatableComposite;

/**
 * Main class.
 * 
 * @author kret
 */
public class Application {

	private static Combo screenshotCombo;

	private static List<SessionUpdatableComposite> updatable = new LinkedList<SessionUpdatableComposite>();

	private static SessionDAO sessionDAO = new SessionDAO(
			SessionFactoryBuilder.getSessionFactory());

	private static SelectionListener selectionListener = new SelectionAdapter() {
		public void widgetSelected(SelectionEvent arg0) {
			updateSelectedSession();
		};
	};

	private static void updateSelectedSession() {
		Session session = new SessionDAO(
				SessionFactoryBuilder.getSessionFactory())
				.getSession(((Date) screenshotCombo.getData(screenshotCombo
						.getItem(screenshotCombo.getSelectionIndex())))
						.getTime());

		for (SessionUpdatableComposite sessionUpdatable : updatable) {
			sessionUpdatable.updateOnSessionChange(session);
		}
	}

	private static void createSessionPicker(Composite parent) {
		Label screenshotPicker = new Label(parent, SWT.NONE);
		screenshotPicker.setText("Choose system session");

		screenshotCombo = new Combo(parent, SWT.NONE);
		// screenshotCombo.add(new Date().toString());
		screenshotCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		updateSessions();
		if (screenshotCombo.getItemCount() > 0) {
			screenshotCombo.select(screenshotCombo.getItemCount() - 1);
		}

		screenshotCombo.addSelectionListener(selectionListener);
	}

	private static void updateSessions() {
		screenshotCombo.removeAll();
		for (Session singleSession : sessionDAO.getSessions()) {
			Date date = new Date(singleSession.getStartTime());

			screenshotCombo.add(date.toString());
			screenshotCombo.setData(date.toString(), date);
		}
	}

	private static void createTabFolder(Shell shell) {
		TabFolder tabFolder = new TabFolder(shell, SWT.BORDER);

		GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
		gd.horizontalSpan = 2;
		tabFolder.setLayoutData(gd);

		// TODO change the way of creating tab pages.
		// Adding cpu info tab page.
		TabItem tabItem = new TabItem(tabFolder, SWT.NULL);
		tabItem.setText("CPU");
		CPUInfoWidget cpuInfoWidget = new CPUInfoWidget(tabFolder);
		tabItem.setControl(cpuInfoWidget);
		updatable.add(cpuInfoWidget);

		// Adding memory page.
		tabItem = new TabItem(tabFolder, SWT.NULL);
		tabItem.setText("Memory");
		MemoryInfoWidget memoryInfoWidget = new MemoryInfoWidget(tabFolder);
		tabItem.setControl(memoryInfoWidget);
		updatable.add(memoryInfoWidget);

		// Adding process page.
		tabItem = new TabItem(tabFolder, SWT.NULL);
		tabItem.setText("Processes");
		ProcessInfoWidget processInfoWidget = new ProcessInfoWidget(tabFolder);
		tabItem.setControl(processInfoWidget);
		updatable.add(processInfoWidget);

		tabItem = new TabItem(tabFolder, SWT.NULL);
		tabItem.setText("Programs");
		ProgramInfoWidget programInfoWidget = new ProgramInfoWidget(tabFolder);
		tabItem.setControl(programInfoWidget);
		updatable.add(programInfoWidget);

		// Adding process page.
		// tabItem = new TabItem(tabFolder, SWT.NULL);
		// tabItem.setText("Disk");
		// DiskInfoWidget diskInfoWidget = new DiskInfoWidget(tabFolder);
		// tabItem.setControl(diskInfoWidget);

		shell.pack();
	}

	public static void main(String[] arg) {

		Display display = Display.getDefault();

		Shell shell = new Shell();
		shell.setLayout(new GridLayout(2, false));

		Menu menuBar = new Menu(shell, SWT.BAR);
		MenuItem fileMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
		fileMenuHeader.setText("&File");

		MenuItem about = new MenuItem(menuBar, SWT.CASCADE);
		about.setText("&About");

		shell.setMenuBar(menuBar);

		createSessionPicker(shell);
		createTabFolder(shell);
		updateSelectedSession();

		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
}
